package jp.ac.waseda.cs.washi.game.ai;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Vector;

import jp.ac.waseda.cs.washi.game.api.CharaInfo;
import jp.ac.waseda.cs.washi.game.api.GameInfo;
import jp.ac.waseda.cs.washi.game.api.GameInvoker;
import jp.ac.waseda.cs.washi.game.api.MapInfo;
import jp.ac.waseda.cs.washi.game.api.Player;
import jp.ac.waseda.cs.washi.game.api.PlayerAction;
import jp.ac.waseda.cs.washi.game.api.PumpkinCoreInfo;
import jp.ac.waseda.cs.washi.gameaiarena.api.Direction4;
import jp.ac.waseda.cs.washi.gameaiarena.api.Point2;
import banshee.ai.ActionFinder;
import banshee.ai.MapInfoUtil;
import banshee.ai.Mode;
import banshee.ai.RawMap;
import banshee.ai.StrategyResult;

public class Banshee implements Player
{
	private MapInfo						map;
	private MapInfoUtil					mapUtil;
	private CharaInfo					player;
	private CharaInfo					enemy;

	private Mode						mode;

	private LinkedList<PlayerAction>	actions;

	private ActionFinder				finder;

	private RawMap						rawMap;

	private static final Direction4		direction[]	= { Direction4.LEFT,
			Direction4.RIGHT, Direction4.UP, Direction4.DOWN };

	@Override
	public PlayerAction execute(GameInfo gameInfo)
	{
		PlayerAction action = actions.peekFirst();
		// System.out.println(action);
		if (action == PlayerAction.NONE) {
			mode = Mode.IDLE;
		}
		if (mode == Mode.IDLE) {
			// System.out.println("idle");
			StrategyResult result = selectMode();
//			System.out.println(mode);
			switch (mode) {
			case CREATE_COMPLETE:
				finder.findComplate(result.dest);
				break;
			case CREATE_MINI:
				finder.findCreateMini(result.dest);
				break;
			}
		}
		return actions.poll();
	}

	private StrategyResult selectMode()
	{
		int w = map.getWidth();
		int h = map.getHeight();
		rawMap.refresh();
		StrategyResult best = StrategyResult.NO_WAY;
		StrategyResult result;

		// create king
		// for (int i = 2; i < w - 2; i++) {
		// for (int j = 2; j < h - 2; j++) {
		// result = rawMap.createKing(new Point(i, j));
		// if (result.ratio() > best.ratio()) {
		// best = result;
		// mode = Mode.CREATE_KING;
		// }
		// }
		// }

		// create mini
//		System.out.println("[mini]");
		for (int i = 2; i < w - 2; i++) {
			for (int j = 2; j < h - 2; j++) {
				result = rawMap.createMini(new Point2(i, j));
//				if(i==17&& j==2) {
//					System.out.println("!");
//				}
//				System.out.println("result:" + result.ratio() + " " + result.dest);
//				if(result.gain == -1) {
//					System.out.println("continue");
//					continue;
//				}
				// System.out.println("result: " + result.gain + ","+result.cost
				// + " " + result.dest);
				
				if (result.ratio() > best.ratio()) {
//					System.out.println("best:" + result.ratio() + " " + result.dest);
					best = result;
					mode = Mode.CREATE_MINI;
				}
			}
		}

		// create complate
//		System.out.println("[complate]");
		for (int i = 1; i < w - 1; i++) {
			for (int j = 1; j < h - 1; j++) {
				result = rawMap.createComplete(new Point2(i, j));
				if (result.ratio() > best.ratio()) {
//					System.out.println("best:" + result.ratio() + " " + result.dest);
					best = result;
					mode = Mode.CREATE_COMPLETE;
				}
			}
		}

		// Mini enemy
		// for (Point v : rawMap.enemyMiniPumpkinCenterLocations) {
		// result = rawMap.breakMini(v);
		// if (result.ratio() > best.ratio()) {
		// best = result;
		// mode = Mode.BREAK_MINI;
		// }
		// }

		// King enemy
		// for (Point v : rawMap.enemyKingPumpkinCenterLocations) {
		// result = rawMap.breakKing(v);
		// if (result.ratio() > best.ratio()) {
		// best = result;
		// mode = Mode.BREAK_KING;
		// }
		// }

		return best;
	}

	@Override
	public void initialize(GameInfo gameInfo)
	{
		map = gameInfo.getMap();
		mapUtil = new MapInfoUtil(map);
		player = gameInfo.getPlayer();
		enemy = gameInfo.getEnemy();
		rawMap = new RawMap(gameInfo);
		mode = Mode.IDLE;
		actions = new LinkedList<PlayerAction>();
		actions.push(PlayerAction.NONE);
		finder = new ActionFinder(gameInfo, rawMap, actions);
	}

	/**
	 * @param args
	 */
	public static void main(String[] args)
	{
		 GameInvoker.startForDebug(new Banshee(), new Sample(), 5);

		//GameInvoker.startForContest(new Banshee(), new DoNothing(), 1);

		// 1Player: 上下左右のキー，スペース，B
		// 2Player: WASZ，Q，E
		// GameInvoker.startForUserPlaying(1);
	}

}
